package com.wei.file.utils;


import com.wei.file.model.HttpRange;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@Slf4j
public class FileUtils {
    public static String getHttpFilePreviewContextType(String filename) {
        String type = "application/octet-stream";
        if (filename == null) {
            log.error("getHttpFilePreviewContextType：filename不能为空");
            return type;
        }
        filename = filename.toLowerCase();
        if (filename.endsWith(".pdf"))
            type = "application/pdf";
        if (filename.endsWith(".png"))
            type = "image/png";
        if (filename.endsWith(".jpg") || filename.endsWith(".jpeg"))
            type = "image/jpeg";
        if (filename.endsWith(".gif"))
            type = "image/gif";
        if (filename.endsWith(".bmp"))
            type = "image/bmp";
        if (filename.endsWith(".webp"))
            type = "image/webp";

        if (filename.endsWith(".mp4"))
            type = "video/mp4";
        if (filename.endsWith(".webm"))
            type = "video/webm";
        if (filename.endsWith(".ogg"))
            type = "video/ogg";

        if (filename.endsWith(".mp3"))
            type = "audio/mpeg";
        if (filename.endsWith(".wav"))
            type = "audio/wav";
        if (filename.endsWith(".webm"))
            type = "audio/webm";
        if (filename.endsWith(".aac"))
            type = "audio/aac";
        return type;
    }

    public static void httpWrite(File file, HttpServletResponse response, HttpServletRequest request, boolean isDown) {
        try {
            // path是指想要下载的文件的路径
            String filename = file.getName();

            // 清空response
            response.reset();
            // 设置response的Header
            if (isDown) {
                response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, StandardCharsets.UTF_8));
                response.setContentType("application/octet-stream");
            } else {
                response.setContentType(FileUtils.getHttpFilePreviewContextType(filename));
            }
            String rangeString = request.getHeader("Range");
            HttpRange range = getRange(rangeString, file);

            response.addHeader("Accept-Ranges", "bytes");


            long contentLength = range.getEnd() - range.getStart();
            response.addHeader("Content-Length", String.valueOf(contentLength));
            response.addHeader("Cache-Control", "max-age=3600");
            if (rangeString != null) {
                response.setStatus(range.getStart() == range.getEnd() ? 200 : 206);
                response.addHeader("Content-Range", "bytes " + range.getStart() + "-" + range.getEnd() + "/" + (file.length() + 1));
            }

//
            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            ServletOutputStream outputStream = response.getOutputStream();
            try (InputStream fis = new BufferedInputStream(fileInputStream);
                 OutputStream os = new BufferedOutputStream(outputStream)) {

                // 定位文件指针到请求的起始位置
                long skipped = fis.skip(range.getStart());
                if (skipped < range.getStart()) {
                    throw new IOException("Unable to skip to requested start position");
                }
                byte[] buffer = new byte[8192]; // 或者根据需要设置合适的缓冲区大小
                int bytesRead;
                long bytesRemaining = range.getSuffixLength();

                // 循环读取文件数据并写入响应输出流
                while ((bytesRead = fis.read(buffer, 0, (int) Math.min(buffer.length, bytesRemaining))) != -1) {
                    os.write(buffer, 0, bytesRead);
                    bytesRemaining -= bytesRead;
                    // 如果已经读取了请求范围内的所有数据，则跳出循环
                    if (bytesRemaining <= 0) {
                        break;
                    }
                }
            }


//            byte[] buffer = new byte[(int) range.getSuffixLength()];
//            System.out.println(range);
//            fis.skip(range.getStart());
//            int read = fis.read(buffer, 0, range.getSuffixLength());
//            response.addHeader("Content-Length", "" + read);
//            fis.close();
//            OutputStream os = new BufferedOutputStream(response.getOutputStream());
//            os.write(buffer);
//            os.flush();
//            os.close();
        } catch (IOException ex) {
//            ex.printStackTrace();
        }
    }

    private static HttpRange getRange(String range, File file) {
        return HttpRange.parse(range, file);
    }
}
